import { AgentSchema } from '@src/components/Schema/AgentSchema'
import { CaseSchema } from '@src/components/Schema/CaseSchema'
import { PartySchema } from '@src/components/Schema/PartySchema'
import scrollIntoView from 'smooth-scroll-into-view-if-needed'
import _ from 'lodash'
import { History } from 'history'
import moment from 'moment'
import { Modal } from 'antd'
import { ExclamationCircleOutlined } from '@ant-design/icons'
import qs from 'query-string'
import { pk } from './config'
import NodeRSA from 'node-rsa'

const { confirm } = Modal
// async函数错误处理方法
export async function awaitWrap<T, U = any> (promise: Promise<T>): Promise<[U | null, T | null]> {
  return await promise
    .then<[null, T]>((data: T) => [null, data])
    .catch<[U, null]>(err => [err, null])
}

// 获取文件地址
export function getObjectURL (file: File): string {
  let url = ''
  // 兼容处理
  if (window.URL.createObjectURL !== undefined) { // basic
    url = window.URL.createObjectURL(file)
  } else if (window.URL !== undefined) { // mozilla
    url = window.URL.createObjectURL(file)
  } else if (window.webkitURL !== undefined) { // webkit
    url = window.webkitURL.createObjectURL(file)
  }
  return url
}

// 过滤对象中为null和undefined的属性
export function filterEmptyAttr (o: { [p: string]: any }): object {
  const r: { [p: string]: any } = {}
  const keys = Object.keys(o)
  keys.forEach(k => {
    if (o[k] !== null && o[k] !== undefined) {
      r[k] = o[k]
    }
  })
  return r
}

// 判断是否未空文本
export function filterEmptyText (v: string | undefined, unit: string = '无'): string {
  return v === undefined || v === '' || v === null ? unit : v
}

// 是否为null、undefind或者空字符串
export function isEmptyString (v?: string): boolean {
  return v === '' || v === null || v === undefined
}

// 格式化金钱
export function formatMoney (v: number | string): string {
  if (typeof v === 'number') {
    return v.toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ',')
  }
  if (typeof v === 'string' && /^\d+(\.\d*)?$/.test(v)) {
    return Number(v).toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ',')
  }
  return '0'
}

// 格式化时间
export function formatDate (v: number, f: string = 'YYYY-MM-DD'): string {
  if (typeof v === 'number') {
    return moment(v * 1000).format(f)
  }
  return v === null || v === undefined ? '无' : String(v)
}
// 仲裁请求文本分项
export function splitItem (text: string): string[] {
  text = text.trim()
  const cnNum = '一二三四五六七八九十' // 中文数字
  const pre = '\\u4e00-\\u9fa5a-zA-Z#\\-：:\'"‘’“”' // 序号前不能接的字符
  const numPre = `${pre}\\d\\.` // 阿拉伯数字序号前不能接的字符
  const split = '、,\\.，．' // 序号后的分隔符
  let nReplace = '$2$3$4$5$6$7\n'
  // 综合判断中文和阿拉伯数字序号
  let r = `(^[${cnNum}\\d][${split}]|(?=[^${numPre}]\\d{3}[${split}])(.)....|(?=[^${numPre}]\\d{2}[${split}])(.)...|(?=[^${numPre}]\\d[${split}])(.)..|(?=[^${pre}][${cnNum}]{3}[${split}])(.)....|(?=[^${pre}][${cnNum}]{2}[${split}])(.)...|(?=[^${pre}][${cnNum}][${split}])(.)..)(?![${cnNum}\\d]+)`
  if (cnNum.includes(text[0])) { // 起始为中文序号时，只判断中文序号
    r = `(^[${cnNum}][${split}]|(?=[^${pre}][${cnNum}]{3}[${split}])(.)....|(?=[^${pre}][${cnNum}]{2}[${split}])(.)...|(?=[^${pre}][${cnNum}][${split}])(.)..)`
    nReplace = '$2$3$4\n'
  } else if (/\d/.test(text[0])) { // 起始为阿拉伯数字序号时，只判断阿拉伯数字序号
    r = `(^\\d[${split}]|(?=[^${numPre}]\\d{3}[${split}])(.)....|(?=[^${numPre}]\\d{2}[${split}])(.)...|(?=[^${numPre}]\\d[${split}])(.)..)(?!\\d+)`
    nReplace = '$2$3$4\n'
  }
  const reg = new RegExp(r, 'gim')
  // const nRef = new RegExp(`(\\r\\n?|\\n)(?![${cnNum}]+[${split}])`, 'g')
  let result = text.replace(reg, nReplace).split('\n').map(li => li.trim()).filter(li => li)
  result = _.uniqWith(result, _.isEqual)
  return result
}

// 表单滚动到第一个错误位置
export const scrollToFirstError = {
  behavior: (actions: any[]) =>
    actions.forEach(({ el, top, left }: { el: any, top: number, left: number }) => {
      el.scrollTop = top - 88
      el.scrollLeft = left
    })
}

// 从案件获取指定账号id的人员信息
export function getSubmittalByAccountid (id: string, d: CaseSchema): { obj: PartySchema | AgentSchema | null, type: string } {
  const aList = d.applicants
  const rList = d.respondents
  const aaList = d.applicant_agents
  const raList = d.respondents_agents
  for (let i = 0; i < aList.length; i++) {
    if (aList[i].accountid === id) {
      return {
        obj: aList[i],
        type: '申请人'
      }
    }
  }
  for (let i = 0; i < rList.length; i++) {
    if (rList[i].accountid === id) {
      return {
        obj: rList[i],
        type: '被申请人'
      }
    }
  }
  for (let i = 0; i < aaList.length; i++) {
    if (aaList[i].accountid === id) {
      return {
        obj: aaList[i],
        type: '申请人'
      }
    }
  }
  for (let i = 0; i < raList.length; i++) {
    if (raList[i].accountid === id) {
      return {
        obj: raList[i],
        type: '被申请人'
      }
    }
  }
  return {
    obj: null,
    type: ''
  }
}

// 跳转到指定锚点
export function scrollToAnchor (hash: string, history?: History): void {
  const d = document.querySelector(hash)
  if (d !== null) {
    if (window.location.hash !== hash && history !== undefined) {
      history.push(hash)
    }
    scrollIntoView(d, {
      behavior: actions => {
        actions.forEach(({ el, top, left }) => {
          el.scrollTop = top - 88
          el.scrollLeft = left
        })
      },
      scrollMode: 'if-needed'
    })
  }
}

// 过滤空值为undifinde
export function filterNullToUndefined (s: any): any {
  if (s === null) {
    return undefined
  }
  return s
}

// 二次确认
export function confirmAction (content: string, callback: () => void): void {
  confirm({
    icon: <ExclamationCircleOutlined />,
    content,
    onOk () {
      callback()
    }
  })
}

// 修改地址参数，并获取新地址
export function resetUrlParams (url: string, params: Object = {}): string {
  const i = url.indexOf('?')
  const path = url.slice(0, i)
  const pString = url.slice(i)
  const o = qs.parse(pString)
  const p = {
    ...o,
    ...params
  }
  const nParams: string = qs.stringify(p)
  return `${path}?${nParams}`
}

// 公钥加密
export function compress (v: string): string {
  const key = new NodeRSA(pk, undefined, { encryptionScheme: 'pkcs1' })
  const str = key.encrypt(v, 'base64')
  if (typeof str === 'string') {
    return str
  }
  return ''
}

// 公钥解密
export function decompress (v: string): string {
  const key = new NodeRSA(pk)
  const str = key.decryptPublic(v, 'utf8')
  if (typeof str === 'string') {
    return str
  }
  return ''
}

// 格式化案件件证件号
export function formatCaseDataLicense (d: CaseSchema): CaseSchema {
  const keys = ['applicant_agents', 'applicants', 'respondents', 'respondents_agents']
  keys.forEach(key => {
    const arr = d[key]
    if (arr instanceof Array && arr.length > 0) {
      arr.forEach(li => {
        if (typeof li.license === 'string' && li.license.length > 0) {
          li.license = decompress(li.license)
        }
      })
    }
  })
  return d
}

export function compressLicense (o: { [k: string]: any }): void {
  if (typeof o.license === 'string' && o.license.length > 0) {
    o.license = compress(o.license)
  }
}

export function decompressLicense (o: { [k: string]: any }): void {
  if (typeof o.license === 'string' && o.license.length > 0) {
    o.license = decompress(o.license)
  }
}
